//------------------------------------------------------------------------------
// pch.h
//------------------------------------------------------------------------------
// File provided for Microsoft Shared Source.
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 
// PARTICULAR PURPOSE.
//------------------------------------------------------------------------------
//
// Prcompiled header
//
//------------------------------------------------------------------------------

#pragma once

#ifndef STRICT
#define STRICT
#endif

// Modify the following defines if you have to target a platform prior to the ones specified below.
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef WINVER                // Allow use of features specific to Windows 95 and Windows NT 4 or later.
#define WINVER 0x0501        // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
#endif

#ifndef _WIN32_WINNT        // Allow use of features specific to Windows NT 4 or later.
#define _WIN32_WINNT    0x0501 // Change this to the appropriate value to target Windows 2000 or later.
#endif                        

#ifndef _WIN32_WINDOWS        // Allow use of features specific to Windows 98 or later.
#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
#endif

#ifndef _WIN32_IE            // Allow use of features specific to IE 4.0 or later.
#define _WIN32_IE 0x0501    // Change this to the appropriate value to target IE 5.0 or later.
#endif

#define _ATL_APARTMENT_THREADED
#define _ATL_NO_AUTOMATIC_NAMESPACE

#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS    // some CString constructors will be explicit

// turns off ATL's hiding of some common and often safely ignored warning messages
#define _ATL_ALL_WARNINGS

#include "resource.h"
#include "resids.h"
#include <atlbase.h>
#include <atlcom.h>
#include <atlctl.h>
#include <atlcoll.h>
#include <atlstr.h>
#include <strsafe.h>
#include "ComObjectWithRef.h"

using namespace ATL;

#define GET_EMBEDDED_PARENT(parentclass, embeddedclass, var) \
    parentclass* var = ((parentclass*)((BYTE*)this - offsetof(parentclass, embeddedclass)));

#define SERVICE_ENTRY_FWD(x, y) \
    if (InlineIsEqualGUID(guidService, x)) \
        if (y) \
            return y->QueryInterface(riid, ppvObject);

#pragma warning(disable:4995)
#pragma warning(disable:4482)
#pragma warning(disable:4278)
#pragma warning(disable:4146)

//The following #import imports the IDTExtensibility2 interface based on it's LIBID
#import "libid:AC0714F2-3D04-11D1-AE7D-00A0C90F26F4" version("1.0") lcid("0") raw_interfaces_only named_guids no_smart_pointers raw_dispinterfaces \
        raw_native_types no_namespace

//The following #import imports VS Command Bars based on it's LIBID
#import "libid:1CBA492E-7263-47BB-87FE-639000619B15" version("8.0") lcid("0") raw_interfaces_only named_guids no_smart_pointers raw_dispinterfaces \
        raw_native_types no_namespace exclude("IAccessible")

//The following #import imports DTE based on it's LIBID
#import "libid:80cc9f66-e7d8-4ddd-85b6-d9e6cd0e93e2" version("8.0") lcid("0") raw_interfaces_only named_guids no_smart_pointers raw_dispinterfaces \
        raw_native_types no_namespace exclude("ULONG_PTR", "LONG_PTR")

//The following #import imports DTE80 based on it's LIBID
#import "libid:1A31287A-4D7D-413e-8E32-3B374931BD89" version("8.0") lcid("0") raw_interfaces_only named_guids no_smart_pointers raw_dispinterfaces \
        raw_native_types no_namespace

#include "FlatSolutionExplorer.h"
#include "Utils.h"

#pragma warning(default:4146 )
#pragma warning(default:4278 )

class DECLSPEC_UUID("A5806B41-0F5B-4374-85F1-BF866E468349") FlatSolutionExplorerLib;

class CFseAddinModule : public CAtlDllModuleT<CFseAddinModule>
{
public:
    DECLARE_LIBID(__uuidof(FlatSolutionExplorerLib))
};

#define BEGIN_REGISTRY_MAP(x) \
static HRESULT WINAPI UpdateRegistry(BOOL fRegister) \
{ \
    const UINT c_uiRes = x; \
    enum REGMAPTYPE \
    { \
        RMT_STATIC, \
        RMT_DYNAMIC, \
    }; \
    static struct REG_REPLACEMENT_MAP \
    { \
        REGMAPTYPE rmt; \
        PCWSTR pszKey; \
        union \
        { \
            void *pv; \
            PCWSTR pszData; \
            HRESULT (*pfnGetReplacement)(__out CString &str); \
        }; \
    } \
    s_rgrrm[] = \
    {

#define REGMAP_STATIC_ENTRY(key, data) \
        { RMT_STATIC, L##key, L##data },

#define REGMAP_DYNAMIC_ENTRY(key, fn) \
        { RMT_DYNAMIC, L##key, fn },

#define END_REGISTRY_MAP() \
        { RMT_STATIC, NULL, NULL }, \
    }; \
    HRESULT hr = S_OK; \
    try \
    { \
        CAtlArray<_ATL_REGMAP_ENTRY> rgrme; \
        CAtlArray<CString> rgDynStrings; \
        rgrme.SetCount(ARRAYSIZE(s_rgrrm)); \
        for (int i = 0; i < ARRAYSIZE(s_rgrrm) && SUCCEEDED(hr); i++) \
        { \
            _ATL_REGMAP_ENTRY &rme = rgrme.GetAt(i); \
            rme.szKey = s_rgrrm[i].pszKey; \
            switch (s_rgrrm[i].rmt) \
            { \
            case RMT_DYNAMIC: \
                { \
                    rgDynStrings.Add(); \
                    CString &strData = rgDynStrings.GetAt(rgDynStrings.GetCount() - 1); \
                    hr = s_rgrrm[i].pfnGetReplacement(strData); \
                    if (SUCCEEDED(hr)) \
                    { \
                        rme.szData = strData; \
                    } \
                } \
                break; \
            case RMT_STATIC: \
                rme.szData = s_rgrrm[i].pszData; \
                break; \
            } \
        } \
        if (SUCCEEDED(hr)) \
        { \
			__if_exists(_Module) \
			{ \
				hr = _Module.UpdateRegistryFromResource(c_uiRes, fRegister, rgrme.GetData()); \
			} \
			__if_not_exists(_Module) \
			{ \
				hr = ATL::_pAtlModule->UpdateRegistryFromResource(c_uiRes, fRegister, rgrme.GetData()); \
			} \
        } \
    } \
    catch (CAtlException &e) \
    { \
        hr = e.m_hr; \
    } \
    return hr; \
}

extern CFseAddinModule _AtlModule;

extern PCWSTR c_szRegRoot;
